package com.jindy.module.outboundorder.service.impl;

import com.jindy.common.core.domain.entity.SysUser;
import com.jindy.common.exception.base.BaseException;
import com.jindy.common.utils.DateUtils;
import com.jindy.common.utils.SecurityUtils;
import com.jindy.common.utils.StringUtils;
import com.jindy.jpush.domain.UniPushDomain;
import com.jindy.jpush.utils.UniJpushUtils;
import com.jindy.module.approvalConfig.domain.ApprovalConfig;
import com.jindy.module.approvalConfig.mapper.ApprovalConfigMapper;
import com.jindy.module.constant.StatusConstants;
import com.jindy.module.jpush.mapper.JpushMapper;
import com.jindy.module.logisticscost.domain.LogisticsCost;
import com.jindy.module.logisticscost.mapper.LogisticsCostMapper;
import com.jindy.module.machine.domain.Machine;
import com.jindy.module.machine.domain.MachineRecord;
import com.jindy.module.machine.dto.MachineDto;
import com.jindy.module.machine.mapper.MachineMapper;
import com.jindy.module.machine.mapper.MachineRecordMapper;
import com.jindy.module.order.domain.Order;
import com.jindy.module.order.domain.OrderProduct;
import com.jindy.module.order.mapper.OrderMapper;
import com.jindy.module.order.mapper.OrderProductMapper;
import com.jindy.module.outboundorder.domain.OutboundOrder;
import com.jindy.module.outboundorder.domain.OutboundOrderMachine;
import com.jindy.module.outboundorder.domain.OutboundOrderProduct;
import com.jindy.module.outboundorder.mapper.OutboundOrderMachineMapper;
import com.jindy.module.outboundorder.mapper.OutboundOrderMapper;
import com.jindy.module.outboundorder.service.IOutboundOrderService;
import com.jindy.module.product.domain.ProductModel;
import com.jindy.module.product.mapper.ProductModelMapper;
import com.jindy.module.serialNum.service.ISySerialNumTService;
import com.jindy.module.stock.domain.Stock;
import com.jindy.module.stock.mapper.StockMapper;
import com.jindy.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 出库单Service业务层处理
 *
 * @author ruoyi
 * @date 2022-10-18
 */
@Service
public class OutboundOrderServiceImpl implements IOutboundOrderService {
    private static final Logger LOGGER = LoggerFactory.getLogger(OutboundOrderServiceImpl.class);
    @Resource
    private OutboundOrderMapper outboundOrderMapper;
    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ProductModelMapper productModelMapper;
    @Resource
    private StockMapper stockMapper;
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderProductMapper orderProductMapper;
    @Resource
    private OutboundOrderMachineMapper outboundOrderMachineMapper;
    @Resource
    private MachineRecordMapper machineRecordMapper;
    @Resource
    private MachineMapper machineMapper;
    @Resource
    private LogisticsCostMapper logisticsCostMapper;

    /**
     * 消息推送设备信息
     */
    @Resource
    private JpushMapper jpushMapper;

    /**
     * 生成流水单号Service
     */
    @Resource
    private ISySerialNumTService serialNumTService;

    /**
     * 审批单配置信息
     */
    @Resource
    private ApprovalConfigMapper approvalConfigMapper;

    /**
     * 查询出库单
     *
     * @param id 出库单主键
     * @return 出库单
     */
    @Override
    public OutboundOrder selectOutboundOrderById(Long id) {
        OutboundOrder obo = outboundOrderMapper.selectOutboundOrderById(id);
        obo.setMachineList(outboundOrderMachineMapper.selectOutboundOrderMachineByOutboundOrderId(id));
        return obo;
    }

    /**
     * 查询出库单列表(父出库单）
     *
     * @param outboundOrder 出库单
     * @return 出库单
     */
    @Override
    public List<OutboundOrder> selectOutboundOrderList(OutboundOrder outboundOrder) {
        outboundOrder.setParentId(0L);
        List<OutboundOrder> list = outboundOrderMapper.selectOutboundOrderList(outboundOrder);
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(or -> {
                OutboundOrderMachine param = new OutboundOrderMachine();
                param.setOutboundOrderId(or.getId());
                List<OutboundOrderMachine> machineList = outboundOrderMachineMapper.selectOutboundOrderMachineList(param);
                or.setMachineList(machineList);
                //                or.setMachineList(outboundOrderMachineMapper.selectOutboundOrderMachineByOutboundOrderId(or.getId()));
                //                List<OutboundOrderMachine> machineList = outboundOrderMachineMapper.selectOutboundOrderMachineByOutboundOrderId(or.getId());
                //                or.setMachineList(machineList);
                // 查询子出库单
                List<OutboundOrder> outboundOrderList = outboundOrderMapper.selectChileOutboundOrderList(or);
                or.setChildOutboundOrder(outboundOrderList);
            });
        }
        return list;
    }


    /**
     * 输入父单id查询出库单列表(子出库单）和子单机器列表
     *
     * @param outboundOrder 出库单
     * @return 出库单
     */
    @Override
    public List<OutboundOrder> selectOutboundOrderList3(OutboundOrder outboundOrder) {
        // 通过父单id查出对应子单列表
        List<OutboundOrder> list3 = outboundOrderMapper.selectChileOutboundOrderList(outboundOrder);
        if (!CollectionUtils.isEmpty(list3)) {
            list3.forEach(childOr -> {
                OutboundOrderMachine param = new OutboundOrderMachine();
                param.setOutboundOrderId(childOr.getId());
                List<OutboundOrderMachine> machineList = outboundOrderMachineMapper.selectOutboundOrderMachineList(param);
                childOr.setMachineList(machineList);
            });
        }
        return list3;
    }

    /**
     * 查询出库单列表(所有数据）
     *
     * @param outboundOrder 出库单
     * @return 出库单集合
     */
    @Override
    public List<OutboundOrder> selectOutboundOrderList2(OutboundOrder outboundOrder) {
        return outboundOrderMapper.selectOutboundOrderList(outboundOrder);
    }


    @Override
    public List<OutboundOrder> selectOutboundOrderListByMachineId(MachineDto machineDto) {
        return outboundOrderMapper.selectOutboundOrderListByMachineId(machineDto);
    }

    /**
     * 新增出库单
     *
     * @param outboundOrder 出库单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertOutboundOrder(OutboundOrder outboundOrder) {

        int result = 0;

        if (outboundOrder.getId() == null) {
            SysUser sysUser = sysUserService.selectUserByUserName(SecurityUtils.getUsername());
            outboundOrder.setCreateBy(sysUser.getUserName());
            outboundOrder.setCreateTime(DateUtils.getNowDate());
            outboundOrder.setSponsor(null == outboundOrder.getSponsor() ? sysUser.getUserId() : outboundOrder.getSponsor());
            outboundOrder.setSponsorName(org.apache.commons.lang3.StringUtils.isBlank(outboundOrder.getSponsorName()) ? sysUser.getUserName() : outboundOrder.getSponsorName());
            outboundOrder.setOrderStatus(StatusConstants.DeliveryStatusConstant.deliveryStatus_1);// 待出库
            // 如果新增的是父单直接赋2，新增的是子单则赋2的同时给父单赋2
            if (outboundOrder.getParentId().equals(0L)) {
                outboundOrder.setExpensesStatus("2");
            }

            result = outboundOrderMapper.insertOutboundOrder(outboundOrder);


            Order order1 = orderMapper.selectOrderById(outboundOrder.getOrderId());
            order1.setOrderStatus(StatusConstants.OrderStatusConstant.orderStatus_7);// 新增父出库单新建成功状态
            orderMapper.updateOrder(order1);
            if (!CollectionUtils.isEmpty(outboundOrder.getMachineList())) {


                // 根据机器状态，判断机器是否可以出库
                outboundOrder.getMachineList().forEach(outboundOrderMachine -> {
                    Machine machine1 = new Machine();
                    machine1.setMachineNo(outboundOrderMachine.getMachineNo());
                    List<Machine> machineList1 = machineMapper.selectMachineList(machine1);
                    Machine machine2 = machineList1.get(0);
                    if (!machine2.getStatus().equals("0")) {
                        throw new RuntimeException(machine2.getStatus() + "此编码机器状态异常，不可出库！");
                    }
                });

                // 关联产品
                outboundOrder.getMachineList().forEach(machine -> {
                    machine.setOutboundOrderId(outboundOrder.getId());
                });
                outboundOrderMachineMapper.insertOutboundOrderMachines(outboundOrder.getMachineList());

                // 审批成功操作
                updateMachine(outboundOrder, outboundOrder.getMachineList());

            }
            if (outboundOrder.getParentId() != 0L) {

                // 校验更改父单物流状态（先填物流，再填出库单）
                // checkLogisticsStatus(outboundOrder);
                // 物流增加出库单子单编号
                // insertOutboundNo(outboundOrder);
                // 出库机器加物流到达时间
                updateOutMachineTime(outboundOrder);
            }

        } else {
            outboundOrder.setUpdateTime(DateUtils.getNowDate());
            if (!CollectionUtils.isEmpty(outboundOrder.getMachineList())) {
                outboundOrderMachineMapper.deleteOutboundOrderMachineByOrderId(outboundOrder.getId());
                // 关联产品
                outboundOrder.getMachineList().forEach(machine -> {
                    machine.setOutboundOrderId(outboundOrder.getId());
                });
                int a = outboundOrderMachineMapper.insertOutboundOrderMachines(outboundOrder.getMachineList());
                LOGGER.info("insertOutboundOrderMachines结果：" + a);
                if (a > 0) {
                    // 审批成功操作
                    updateMachine(outboundOrder, outboundOrder.getMachineList());
                }

            }
            if (outboundOrder.getParentId() != 0L) {
                updateOutMachineTime(outboundOrder);
            }

            result = outboundOrderMapper.updateOutboundOrder(outboundOrder);
        }

        return result;
    }

    /**
     * 出库成功
     */
    void updateStock(OutboundOrder outboundOrder, List<OutboundOrderProduct> productList) {
        Order order = orderMapper.selectOrderById(outboundOrder.getOrderId());
        if (order != null) {
            order.setDeliveryStatus(StatusConstants.DeliveryStatusConstant.deliveryStatus_2);
            int allDeliveryCount = 0;// 是否全部出库
            for (OutboundOrderProduct product : productList) {
                // 1:修改产品-模型中的数量
                ProductModel productModel = new ProductModel();
                productModel.setProductId(product.getProductId().toString());
                productModel.setModel(productModel.getModel());
                productModel = productModelMapper.selectProductModel(productModel);
                productModel.setQuantity(productModel.getQuantity() - product.getOutboundQuantity());
                productModelMapper.updateProductModel(productModel);

                // 2:修改仓库库存
                Stock stock = new Stock();
                stock.setProductId(product.getProductId());
                stock.setModel(productModel.getModel());
                stock.setWarehouseId(product.getOutboundWarehouseId());
                List<Stock> stocks = stockMapper.selectStockList(stock);
                if (!CollectionUtils.isEmpty(stocks)) {
                    stock = stocks.get(0);
                    stock.setQuantity(stock.getQuantity() - product.getOutboundQuantity());
                    stock.setAvailableQuantity(stock.getAvailableQuantity() - product.getOutboundQuantity());
                    stockMapper.updateStock(stock);
                }

                // 3:修改订单表的待出库数量
                // 查询订单明细
                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setOrderId(order.getId());
                orderProduct.setProductId(product.getProductId());
                orderProduct.setModel(product.getModel());
                List<OrderProduct> orderProducts = orderProductMapper.selectOrderProductList(orderProduct);
                if (!CollectionUtils.isEmpty(orderProducts)) {
                    orderProduct = orderProducts.get(0);
                    if (orderProduct.getUndeliveryQuantity().equals(product.getOutboundQuantity())) {
                        allDeliveryCount += 1;
                    }
                    orderProduct.setUndeliveryQuantity(orderProduct.getUndeliveryQuantity() - product.getOutboundQuantity());
                    orderProductMapper.updateOrderProduct(orderProduct);
                }
            }
            if (allDeliveryCount == productList.size()) {
                order.setDeliveryStatus(StatusConstants.DeliveryStatusConstant.deliveryStatus_2);
            }
            orderMapper.updateOrder(order);
        }


    }

    /**
     * 出库成功
     */
    @Transactional(rollbackFor = Exception.class)
    void updateMachine(OutboundOrder outboundOrder, List<OutboundOrderMachine> machineList) {
        Order order = orderMapper.selectOrderById(outboundOrder.getOrderId());
        LOGGER.info("出库成功" + order.toString());
        if (order != null) {


            // 给机器添加入库记录
            List<MachineRecord> machineRecords = new ArrayList<>();
            for (OutboundOrderMachine machine : machineList) {
                // 1:修改产品-模型中的数量
                ProductModel productModel = new ProductModel();
                productModel.setProductId(machine.getProductId().toString());
                productModel.setModel(machine.getModel());
                productModel = productModelMapper.selectProductModel(productModel);
                productModel.setQuantity(productModel.getQuantity() - 1);
                productModelMapper.updateProductModel(productModel);

                // 2:修改仓库库存
                Stock stock = new Stock();
                stock.setProductId(machine.getProductId());
                stock.setModel(machine.getModel());
                stock.setWarehouseId(machine.getWarehouseId());
                List<Stock> stocks = stockMapper.selectStockList(stock);
                if (!CollectionUtils.isEmpty(stocks)) {
                    stock = stocks.get(0);
                    stock.setQuantity(stock.getQuantity() - 1);
                    stock.setAvailableQuantity(stock.getAvailableQuantity() - 1);
                    stockMapper.updateStock(stock);
                }

                // 3:修改订单表的待出库数量
                // 查询订单明细
                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setOrderId(order.getId());
                orderProduct.setProductId(machine.getProductId());
                orderProduct.setModel(machine.getModel());
                List<OrderProduct> orderProducts = orderProductMapper.selectOrderProductList(orderProduct);
                LOGGER.info("订单表的待出库数量:" + CollectionUtils.isEmpty(orderProducts));
                if (!CollectionUtils.isEmpty(orderProducts)) {
                    orderProduct = orderProducts.get(0);
                      /*  if(orderProduct.getUndeliveryQuantity().equals(1L)){
                            allDeliveryCount +=1;
                        }*/
                    LOGGER.info("订单表的待出库数量2:" + orderProduct.getUndeliveryQuantity());
                    orderProduct.setUndeliveryQuantity(orderProduct.getUndeliveryQuantity() - 1);
                    orderProduct.setDeliveryQuantity(orderProduct.getDeliveryQuantity() + 1);
                    orderProductMapper.updateOrderProduct(orderProduct);
                }

                // 通过机器编号查询机器信息
                Machine machine2 = new Machine();
                machine2.setMachineNo(machine.getMachineNo());
                Machine machine1 = machineMapper.selectMachineList2(machine2).get(0);

                // 4.机器添加出库记录ni buzhi
                MachineRecord record = new MachineRecord();
                record.setOutboundId(outboundOrder.getId());
                record.setOutboundNo(outboundOrder.getOutboundNo());
                record.setOutboundTime(outboundOrder.getOutboundTime());
                record.setMachineId(machine.getMachineId());
                record.setMachineNo(machine.getMachineNo());
                record.setOrderNo(outboundOrder.getOrderNo());
                record.setOrderId(outboundOrder.getOrderId());
                record.setWarehouseId(machine.getWarehouseId());
                record.setWarehouseName(machine.getWarehouseName());
                record.setMachineSerialNumber(machine1.getMachineSerialNumber());
                // 添加机器使用状态为状态为使用中
                record.setStatus(StatusConstants.MachineRecordStatusConstant.machineRecordStatus_2);
                machineRecords.add(record);

                // 5.修改机器的状态为使用中
                Machine ma = machineMapper.selectMachineById(machine.getMachineId());
                if (ma != null) {
                    ma.setStatus(StatusConstants.MachineStatusConstant.machineStatus_2);
                    machineMapper.updateMachine(ma);
                }

                // 出库机器表加机器每日租金
                //                OrderProduct orderProduct1 = new OrderProduct();
                //                orderProduct1.setOrderId(outboundOrder.getOrderId());
                //                orderProduct1.setModel(machine.getModel());
                //                List<OrderProduct> orderProductList = orderProductMapper.selectOrderProductList(orderProduct1);
                //                if(!CollectionUtils.isEmpty(orderProductList)){
                //                    OrderProduct orderProduct2 = orderProductList.get(0);
                //                    OutboundOrderMachine outboundOrderMachine = outboundOrderMachineMapper.selectOutboundOrderMachineById(machine.getId());
                //                    outboundOrderMachine.setDailyRent(orderProduct2.getDailyRent());
                //                }
                OrderProduct orderProduct1 = new OrderProduct();
                orderProduct1.setOrderId(outboundOrder.getOrderId());
                orderProduct1.setModel(machine.getModel());
                List<OrderProduct> orderProductList = orderProductMapper.selectOrderProductList(orderProduct1);

                if (!CollectionUtils.isEmpty(orderProductList)) {
                    OrderProduct orderProduct2 = orderProductList.get(0);

                    OutboundOrderMachine outboundOrderMachine = new OutboundOrderMachine();
                    outboundOrderMachine.setOutboundOrderId(machine.getOutboundOrderId());
                    outboundOrderMachine.setMachineNo(machine.getMachineNo());
                    List<OutboundOrderMachine> outboundOrderMachineList = outboundOrderMachineMapper.selectOutboundOrderMachineList(outboundOrderMachine);
                    OutboundOrderMachine outboundOrderMachine1 = outboundOrderMachineList.get(0);
                    outboundOrderMachine1.setDailyRent(orderProduct2.getDailyRent());
                    outboundOrderMachineMapper.updateOutboundOrderMachine(outboundOrderMachine);
                }


                // 6.添加物流费用
                //                LogisticsCost cost = new LogisticsCost();
                //                cost.setOrderId(outboundOrder.getOrderId().toString());
                //                cost.setOrderProperty("2");
                //                cost.setLogisticsExpenses(outboundOrder.getLogisticsExpenses().toString());
                //                cost.setProjectName(order.getProjectName());
                //                logisticsCostMapper.insertLogisticsCost(cost);

            }
            machineRecordMapper.insertMachineRecords(machineRecords);

            // 查询父级出库单
            OutboundOrder parent = outboundOrderMapper.selectOutboundOrderById(outboundOrder.getParentId());
            if (parent == null) {
                throw new RuntimeException("出库单不存在，请联系管理员！");
            }
            // 查看订单是否出库完毕
            Integer undeliveryQuantity = orderProductMapper.getUndeliveryQuantityCount(order.getId());
            LOGGER.info("查看订单是否出库完毕:" + undeliveryQuantity);
            if (undeliveryQuantity != null && undeliveryQuantity.intValue() == 0) {
                LOGGER.info("查看订单是出库完毕");
                order.setDeliveryStatus(StatusConstants.DeliveryStatusConstant.deliveryStatus_2);
                order.setShipmentStatus(StatusConstants.ShipmentStatusConstant.shipmentStatus_3);// 已发货
                order.setOrderStatus(StatusConstants.OrderStatusConstant.orderStatus_2);// 执行中
                orderMapper.updateOrder(order);
                parent.setOrderStatus(StatusConstants.DeliveryStatusConstant.deliveryStatus_2);
            }

            // 修改出库状态
            outboundOrder.setOrderStatus(StatusConstants.DeliveryStatusConstant.deliveryStatus_2);// 已出库
            outboundOrder.setUndeliveryQuantity(undeliveryQuantity);
            outboundOrderMapper.updateOutboundOrder(outboundOrder);
            parent.setUndeliveryQuantity(undeliveryQuantity);
            LOGGER.info("修改父级:" + parent.toString());
            outboundOrderMapper.updateOutboundOrder(parent);
            if (StatusConstants.DeliveryStatusConstant.deliveryStatus_2.equals(parent.getOrderStatus())){
                //  通知发起人
                List<String> regIds = jpushMapper.selectRegistrationIdsByUserIds(Collections.singletonList(order.getSponsor()));
                if (!CollectionUtils.isEmpty(regIds)) {
                    UniJpushUtils.doPost(new UniPushDomain(regIds, "湿云", order.getOrderNo() + "租赁订单已出库。"));
                }
                // 通知物流人员
                noticeLogisticsPersonnel(order.getOrderNo());
            }
        }
    }


    /**
     * 修改出库单
     *
     * @param outboundOrder 出库单
     * @return 结果
     */
    @Override
    public int updateOutboundOrder(OutboundOrder outboundOrder) {
        outboundOrder.setUpdateTime(DateUtils.getNowDate());
        int result = 0;
        try {
            if (!CollectionUtils.isEmpty(outboundOrder.getMachineList())) {
                outboundOrderMachineMapper.deleteOutboundOrderMachineByOrderId(outboundOrder.getId());
                // 关联产品
                outboundOrder.getMachineList().forEach(machine -> {
                    machine.setOutboundOrderId(outboundOrder.getId());
                });
                int a = outboundOrderMachineMapper.insertOutboundOrderMachines(outboundOrder.getMachineList());
                LOGGER.info("insertOutboundOrderMachines结果：" + a);

                // 审批成功操作
                if (a > 0) {
                    updateMachine(outboundOrder, outboundOrder.getMachineList());
                }
            }

            if (outboundOrder.getParentId() != 0L) {

                // 校验更改父单物流状态（先填物流，再填出库单）
                // checkLogisticsStatus(outboundOrder);
                // 物流增加出库单子单编号
                // insertOutboundNo(outboundOrder);
                // 出库机器加物流到达时间
                updateOutMachineTime(outboundOrder);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return outboundOrderMapper.updateOutboundOrder(outboundOrder);
    }

    /**
     * 批量删除出库单
     *
     * @param ids 需要删除的出库单主键
     * @return 结果
     */
    @Override
    public int deleteOutboundOrderByIds(Long[] ids) {
        return outboundOrderMapper.deleteOutboundOrderByIds(ids);
    }

    /**
     * 删除出库单信息
     *
     * @param id 出库单主键
     * @return 结果
     */
    @Override
    public int deleteOutboundOrderById(Long id) {
        return outboundOrderMapper.deleteOutboundOrderById(id);
    }

    @Override
    public OutboundOrder getNo(OutboundOrder order) {
        order.setParentId(0L);
        List<OutboundOrder> list = outboundOrderMapper.selectOutboundOrderList(order);
        if (!CollectionUtils.isEmpty(list)) {
            OutboundOrder outboundOrder = list.get(0);
            OutboundOrder now = new OutboundOrder();
            now.setParentId(outboundOrder.getId());
            Integer no = outboundOrderMapper.getMaxNo(outboundOrder);
            if (no == null) {
                no = 1;
            } else {
                no = no + 1;
            }
            now.setOutboundNo(outboundOrder.getOutboundNo() + "-" + no);
            return now;
        }
        return null;
    }

    /**
     * 根据出库单编号查询
     *
     * @param
     * @return
     */
    @Override
    public List<OutboundOrder> getByOutboundNo(String[] outboundNo) {
        return outboundOrderMapper.getByOutboundNo(outboundNo);
    }


    /**
     * 校验更改父单物流状态（先填物流，再添出库单）
     *
     * @param outboundOrder
     * @return 结果
     */
    void checkLogisticsStatus(OutboundOrder outboundOrder) {
        if (outboundOrder.getOrderId() != null) {

            int costSum = 0;

            // 该订单出库物流条数
            LogisticsCost logisticsCost = new LogisticsCost();
            List<LogisticsCost> logisticsCostList = new ArrayList<>();
            logisticsCost.setOrderId(outboundOrder.getOrderId());
            List<LogisticsCost> logisticsCostList2 = logisticsCostMapper.selectLogisticsCostList(logisticsCost);
            if (!CollectionUtils.isEmpty(logisticsCostList2)) {// 过滤入库申请物流
                logisticsCostList2.forEach(logistics -> {
                    if (logistics.getReturnApplyNo() == null || logistics.getReturnApplyNo().equals("")) {
                        logisticsCostList.add(logistics);
                    }
                });
            }
            if (!CollectionUtils.isEmpty(logisticsCostList)) {
                // 去重
                List<LogisticsCost> list3 = logisticsCostList.stream().collect(
                        Collectors.collectingAndThen(Collectors.toCollection(
                                () -> new TreeSet<>(Comparator.comparing(LogisticsCost::getSerialNumber))), ArrayList::new));

                costSum = list3.size();
            } else {
                costSum = logisticsCostList.size();
            }

            // 出库单父单和子单条数
            OutboundOrder outboundOrder2 = new OutboundOrder();
            outboundOrder2.setOrderId(outboundOrder.getOrderId());
            List<OutboundOrder> list = outboundOrderMapper.selectOutboundOrderList(outboundOrder2);
            List<OutboundOrder> list2 = new ArrayList<>();
            // 父单
            outboundOrder2.setParentId(0L);
            List<OutboundOrder> list1 = outboundOrderMapper.selectOutboundOrderList(outboundOrder2);
            if (!CollectionUtils.isEmpty(list1)) {
                OutboundOrder outboundOrder1 = list1.get(0);
                // 筛选出子单
                if (!CollectionUtils.isEmpty(list)) {
                    list.forEach(or -> {
                        if (or.getParentId() != 0L) {
                            list2.add(or);
                        }
                    });
                }
                // 出库子单条数
                int outSum = list2.size();

                // 根据情况给父出库单赋物流填写状态状态
                if (costSum >= outSum) {
                    outboundOrder1.setExpensesStatus("1");// 已完全填写物流
                    outboundOrderMapper.updateOutboundOrder(outboundOrder1);
                }
                if (costSum < outSum) {
                    outboundOrder1.setExpensesStatus("2");// 未完全填写物流
                    outboundOrderMapper.updateOutboundOrder(outboundOrder1);
                }
            }
        }
    }

    /**
     * 物流增加出库单编号
     *
     * @param outboundOrder
     * @return 结果
     */
    void insertOutboundNo(OutboundOrder outboundOrder) {
        // 截取出库单子单编号中相应的数字（子单绑定物流）
        String str1 = outboundOrder.getOutboundNo().substring(0, outboundOrder.getOutboundNo().indexOf("-"));
        String number = outboundOrder.getOutboundNo().substring(str1.length() + 1);

        // 该订单出库物流
        LogisticsCost logisticsCost = new LogisticsCost();
        List<LogisticsCost> logisticsCostList = new ArrayList<>();
        logisticsCost.setOrderId(outboundOrder.getOrderId());
        List<LogisticsCost> logisticsCostList2 = logisticsCostMapper.selectLogisticsCostList(logisticsCost);
        if (!CollectionUtils.isEmpty(logisticsCostList2)) {// 过滤入库申请物流
            logisticsCostList2.forEach(logistics -> {
                if (logistics.getReturnApplyNo() == null || logistics.getReturnApplyNo().equals("")) {
                    logisticsCostList.add(logistics);
                }
            });
        }
        // 把出库编号加到对应的子单中
        if (!CollectionUtils.isEmpty(logisticsCostList)) {
            logisticsCostList.forEach(cost -> {
                if (cost.getSerialNumber().equals(number)) {
                    cost.setOutboundNo(outboundOrder.getOutboundNo());
                    logisticsCostMapper.updateLogisticsCost(cost);
                }
            });
        }
    }

    /**
     * 出库机器加物流到达时间
     *
     * @param outboundOrder
     * @return 结果
     */
    void updateOutMachineTime(OutboundOrder outboundOrder) {
        // 截取出库单子单编号中相应的数字（子单绑定物流）
        //        String str1 = outboundOrder.getOutboundNo().substring(0,outboundOrder.getOutboundNo().indexOf("-"));
        //        String number = outboundOrder.getOutboundNo().substring(str1.length()+1);

        // 该订单出库物流
        LogisticsCost logisticsCost = new LogisticsCost();
        List<LogisticsCost> logisticsCostList = new ArrayList<>();
        logisticsCost.setOrderId(outboundOrder.getOrderId());
        List<LogisticsCost> logisticsCostList2 = logisticsCostMapper.selectLogisticsCostList(logisticsCost);
        if (!CollectionUtils.isEmpty(logisticsCostList2)) {// 过滤入库申请物流
            logisticsCostList2.forEach(logistics -> {
                if (logistics.getReturnApplyNo() == null || logistics.getReturnApplyNo().equals("")) {
                    logisticsCostList.add(logistics);
                }
            });
        }

        if (!CollectionUtils.isEmpty(logisticsCostList)) {
            // 去重，只留一个出库记录
            //            List<LogisticsCost> list3 = logisticsCostList.stream().collect(
            //                    Collectors.collectingAndThen(Collectors.toCollection(
            //                            () -> new TreeSet<>(Comparator.comparing(LogisticsCost::getSerialNumber))), ArrayList::new));
            // 找到对应的物流记录
            logisticsCostList.forEach(logistics -> {
                //                if(logistics.getSerialNumber().equals(number) && logistics.getArrivalDate()!=null){
                if (logistics.getArrivalDate() != null) {
                    OutboundOrderMachine outboundOrderMachine = new OutboundOrderMachine();
                    outboundOrderMachine.setOutboundOrderId(outboundOrder.getId());
                    // 查出对应出库机器数据
                    List<OutboundOrderMachine> list2 = outboundOrderMachineMapper.selectOutboundOrderMachineList(outboundOrderMachine);
                    if (!CollectionUtils.isEmpty(list2)) {
                        list2.forEach(machine -> {
                            machine.setLogisticsTime(logistics.getArrivalDate());
                            outboundOrderMachineMapper.updateOutboundOrderMachine(machine);
                        });
                    }
                }
            });
        }
    }

    /**
     * 新增出库单
     *
     * @param serialNum
     */
    public void createOutboundOrder(String serialNum) {
        // 生成流水单号
        String number = serialNumTService.generateSerialNum("CKDD");
        if (StringUtils.isBlank(number)) {
            throw new BaseException("新增出库单-获取出库单号失败");
        }
        // 获取租赁订单信息
        Order order = orderMapper.selectOrderByOrderNo(serialNum);
        if (Objects.isNull(order)) {
            throw new BaseException(StringUtils.format("新增出库单-获取订单信息失败,订单编号：{}", serialNum));
        }
        // 新增出库单
        OutboundOrder outboundOrder = new OutboundOrder();
        outboundOrder.setParentId(0L);
        outboundOrder.setOrderNo(serialNum);
        outboundOrder.setOutboundNo(number);
        outboundOrder.setSponsor(order.getSalesman());
        outboundOrder.setSponsorName(order.getSalesmanName());
        outboundOrder.setCustomerId(order.getCustomerId());
        outboundOrder.setCustomerName(order.getCustomerName());
        outboundOrder.setOrderType(order.getOrderType());
        outboundOrder.setOrderId(order.getId());
        outboundOrder.setOutboundWarehouseId(order.getDeliveryWarehouseId());
        outboundOrder.setOutboundWarehouseName(order.getDeliveryWarehouseName());
        outboundOrder.setTotalDailyRent(order.getTotalDailyRent());
        outboundOrder.setMaterialSpecification(order.getAccessoriesInstruction());
        outboundOrder.setAddress(order.getAddress());
        insertOutboundOrder(outboundOrder);
    }

    /**
     * 通知物流人员
     */
    private void noticeLogisticsPersonnel(String orderNo) {
        try {
            List<ApprovalConfig> approvalConfigList = approvalConfigMapper.selectApprovalConfigList(new ApprovalConfig("WLRY", "1"));
            if (CollectionUtils.isEmpty(approvalConfigList)) {
                throw new BaseException("请检查审批配置信息：WLRY");
            }
            List<String> registrationIdsByUserIds = jpushMapper.selectRegistrationIdsByUserIds(approvalConfigList.stream().map(ApprovalConfig::getUserId).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(registrationIdsByUserIds)){
                throw new BaseException("扫码出库完成-物流人员设备id不存在");
            }
            UniJpushUtils.doPost(new UniPushDomain(registrationIdsByUserIds,"湿云",orderNo+"租赁订单扫码出库完成。"));
        } catch (Exception e) {
            LOGGER.error("扫码出库完成-通知物流人员失败", e);
        }
    }
}
